package com.yeskery.nut.cloud.feign;

import com.yeskery.nut.application.ServerEventContext;
import com.yeskery.nut.bean.ApplicationContext;
import com.yeskery.nut.bean.NoSuchBeanException;
import com.yeskery.nut.plugin.ServerEventPlugin;
import com.yeskery.nut.util.http.HttpConfiguration;
import com.yeskery.nut.util.http.HttpUtils;
import com.yeskery.nut.util.http.ResponseEntity;

/**
 * 默认的feign请求处理类
 * @author YESKERY
 * 2024/1/19
 */
public class DefaultFeignRequestHandler extends ResponsiveFeignRequestHandler implements ServerEventPlugin {

    /**
     * 构建响应式feign请求处理类
     * @param applicationContext  响应转换接口
     */
    public DefaultFeignRequestHandler(ApplicationContext applicationContext) {
        super(applicationContext);
    }

    @Override
    protected String getResponseAsString(FeignRequestMetadata feignRequestMetadata, FeignRequestData feignRequestData) {
        HttpConfiguration configuration = getConfiguration();
        if (feignRequestMetadata.getMethod() == com.yeskery.nut.core.Method.GET) {
            return HttpUtils.getDefaultInstance().doGetString(getOriginalRequestUrl(feignRequestMetadata, feignRequestData),
                    feignRequestData.getHeaders(), configuration);
        } else if (feignRequestMetadata.getMethod() == com.yeskery.nut.core.Method.POST) {
            if (feignRequestData.getBodyResource() != null) {
                return HttpUtils.getDefaultInstance().doPostString(getOriginalRequestUrl(feignRequestMetadata, feignRequestData),
                        feignRequestData.getHeaders(), feignRequestData.getBodyResource().getInputStream(),
                        getOriginalRequestMediaType(feignRequestData), configuration);
            } else {
                return HttpUtils.getDefaultInstance().doPostString(getOriginalRequestUrl(feignRequestMetadata, feignRequestData),
                        feignRequestData.getHeaders(), getOriginalRequestBodyString(feignRequestData),
                        getOriginalRequestMediaType(feignRequestData), configuration);
            }
        } else if (feignRequestMetadata.getMethod() == com.yeskery.nut.core.Method.PUT) {
            if (feignRequestData.getBodyResource() != null) {
                return HttpUtils.getDefaultInstance().doPutString(getOriginalRequestUrl(feignRequestMetadata, feignRequestData),
                        feignRequestData.getHeaders(), feignRequestData.getBodyResource().getInputStream(),
                        getOriginalRequestMediaType(feignRequestData), configuration);
            } else {
                return HttpUtils.getDefaultInstance().doPutString(getOriginalRequestUrl(feignRequestMetadata, feignRequestData),
                        feignRequestData.getHeaders(), getOriginalRequestBodyString(feignRequestData),
                        getOriginalRequestMediaType(feignRequestData), configuration);
            }
        } else if (feignRequestMetadata.getMethod() == com.yeskery.nut.core.Method.DELETE) {
            if (feignRequestData.getBodyResource() != null) {
                return HttpUtils.getDefaultInstance().doDeleteString(getOriginalRequestUrl(feignRequestMetadata, feignRequestData),
                        feignRequestData.getHeaders(), feignRequestData.getBodyResource().getInputStream(),
                        getOriginalRequestMediaType(feignRequestData), configuration);
            } else {
                return HttpUtils.getDefaultInstance().doDeleteString(getOriginalRequestUrl(feignRequestMetadata, feignRequestData),
                        feignRequestData.getHeaders(), getOriginalRequestBodyString(feignRequestData),
                        getOriginalRequestMediaType(feignRequestData), configuration);
            }
        }
        throw new FeignClientException("UnSupport Feign Client Request Method[" + feignRequestMetadata.getMethod() + "].");
    }

    @Override
    protected ResponseEntity<byte[]> getResponseAsEntity(FeignRequestMetadata feignRequestMetadata, FeignRequestData feignRequestData) {
        HttpConfiguration configuration = getConfiguration();
        if (feignRequestMetadata.getMethod() == com.yeskery.nut.core.Method.GET) {
            return HttpUtils.getDefaultInstance().doGet(getOriginalRequestUrl(feignRequestMetadata, feignRequestData),
                    feignRequestData.getHeaders(), configuration);
        } else if (feignRequestMetadata.getMethod() == com.yeskery.nut.core.Method.POST) {
            if (feignRequestData.getBodyResource() != null) {
                return HttpUtils.getDefaultInstance().doPost(getOriginalRequestUrl(feignRequestMetadata, feignRequestData),
                        feignRequestData.getHeaders(), feignRequestData.getBodyResource().getInputStream(),
                        getOriginalRequestMediaType(feignRequestData), configuration);
            } else {
                return HttpUtils.getDefaultInstance().doPost(getOriginalRequestUrl(feignRequestMetadata, feignRequestData),
                        feignRequestData.getHeaders(), getOriginalRequestBodyString(feignRequestData),
                        getOriginalRequestMediaType(feignRequestData), configuration);
            }
        } else if (feignRequestMetadata.getMethod() == com.yeskery.nut.core.Method.PUT) {
            if (feignRequestData.getBodyResource() != null) {
                return HttpUtils.getDefaultInstance().doPut(getOriginalRequestUrl(feignRequestMetadata, feignRequestData),
                        feignRequestData.getHeaders(), feignRequestData.getBodyResource().getInputStream(),
                        getOriginalRequestMediaType(feignRequestData), configuration);
            } else {
                return HttpUtils.getDefaultInstance().doPut(getOriginalRequestUrl(feignRequestMetadata, feignRequestData),
                        feignRequestData.getHeaders(), getOriginalRequestBodyString(feignRequestData),
                        getOriginalRequestMediaType(feignRequestData), configuration);
            }
        } else if (feignRequestMetadata.getMethod() == com.yeskery.nut.core.Method.DELETE) {
            if (feignRequestData.getBodyResource() != null) {
                return HttpUtils.getDefaultInstance().doDelete(getOriginalRequestUrl(feignRequestMetadata, feignRequestData),
                        feignRequestData.getHeaders(), feignRequestData.getBodyResource().getInputStream(),
                        getOriginalRequestMediaType(feignRequestData), configuration);
            } else {
                return HttpUtils.getDefaultInstance().doDelete(getOriginalRequestUrl(feignRequestMetadata, feignRequestData),
                        feignRequestData.getHeaders(), getOriginalRequestBodyString(feignRequestData),
                        getOriginalRequestMediaType(feignRequestData), configuration);
            }
        }
        throw new FeignClientException("UnSupport Feign Client Request Method[" + feignRequestMetadata.getMethod() + "].");
    }

    @Override
    public void afterStart(ServerEventContext serverEventContext) {
        for (FeignRequestInterceptor feignRequestInterceptor : getApplicationContext().getBeans(FeignRequestInterceptor.class)) {
            this.addInterceptor(feignRequestInterceptor);
        }
    }

    /**
     * 获取Http配置对象
     * @return Http配置对象
     */
    private HttpConfiguration getConfiguration() {
        try {
            HttpConfigurationSupport httpConfigurationSupport = getApplicationContext().getBean(HttpConfigurationSupport.class);
            return httpConfigurationSupport.getHttpConfiguration();
        } catch (NoSuchBeanException e) {
            return HttpConfiguration.getDefaultHttpConfiguration();
        }
    }
}
